#include "RenderNode.h"

RenderNode::RenderNode()
{
	m_SetTransform = false;

	for( unsigned int i = 0; i < 16; i ++ )
	{
		m_Transform[i] = 0.0f;
	}
	for( unsigned int i = 0; i < 16; i +=5 )
	{
		m_Transform[i] = 1.0f;
	}

	for( unsigned int i = 0; i < 3; i ++ )
	{
		m_Scale[i] = 1.0f;
	}

	m_ObjName.clear();
	m_resetMaterials.clear();
	m_ChidlRenderNodes.clear();
	m_SMat.clear();
	m_Father = NULL;
}
RenderNode::~RenderNode()
{
 	if( m_ChidlRenderNodes.size() > 0 )
 	{
   		for( std::vector<RenderNode*>::iterator rnit = m_ChidlRenderNodes.begin();
   			rnit != m_ChidlRenderNodes.end(); rnit ++ )
   		{
   			RenderNode* rd = *rnit;
   			if( rd )
   			{
   				delete rd;
   			}
   		}
 	}
}
void RenderNode::SetTransform( float trf[16] )
{
	for( unsigned int i = 0; i < 16; i ++ )
	{
		m_Transform[i] = trf[i];
	}
}
void RenderNode::SetScale( float s[3] )
{
	for( unsigned int i = 0; i < 3; i ++ )
	{
		m_Scale[i] = s[i];
	}
}
void RenderNode::SetObj( std::string obj_name )
{
	m_ObjName = obj_name;
}
void RenderNode::ResetMaterials( const std::vector<std::string>& mats )
{
	for( unsigned int i = 0; i < mats.size(); i ++ )
	{
		m_resetMaterials.push_back( mats[i] );
	}
}
void RenderNode::SetSMat( const std::string& smat_name )
{
	m_SMat = smat_name;
}
void RenderNode::AddChild( RenderNode* rd )
{
	m_ChidlRenderNodes.push_back( rd );
	rd->SetFather( this );
}
void RenderNode::SetFather( RenderNode* rd )
{
	m_Father = rd;
}
RenderNode* RenderNode::GetFather()
{
	return m_Father;
}
float* RenderNode::GetTransform()
{
	return m_Transform;
}
float* RenderNode::GetScale()
{
	return m_Scale;
}
std::string RenderNode::GetObj()
{
	return m_ObjName;
}
std::vector<std::string> RenderNode::GetResetMaterials()
{
	return m_resetMaterials;
}
unsigned int RenderNode::ChildNum()
{
	return m_ChidlRenderNodes.size();
}
RenderNode* RenderNode::GetChild( int idx )
{
	if( idx >= 0 && idx < m_ChidlRenderNodes.size() )
	{
		return m_ChidlRenderNodes[idx];
	}

	return NULL;
}
std::vector<RenderNode*>& RenderNode::GetChild()
{
	return m_ChidlRenderNodes;
}
void RenderNode::Show()
{
	std::cout<< "name " << m_ObjName << "\n";
	std::cout<< " --- ";
	std::cout<< m_ChidlRenderNodes.size() << "\n";
	for( unsigned int rnit = 0; rnit < m_ChidlRenderNodes.size(); rnit ++ )
	{
		RenderNode* rn = m_ChidlRenderNodes[rnit];
		if( rn == NULL )
		{
			std::cout<< "(RenderNode)::Show() Fatal error\n";
		}
		rn->Show();
		std::cout<< "\n";
	}
}
void RenderNode::Paint()
{
//  	if( m_ObjName != "models/skybox.obj" && !m_ObjName.empty() )
//  	{
//  		return;
//  	}
	glPushMatrix();

	glMultMatrixf( m_Transform );
	glScalef( m_Scale[0], m_Scale[1], m_Scale[2] );

	if( m_resetMaterials.size() > 0 )
	{
		RenderObj::GetInstance()->ResetMaterials( m_resetMaterials );
	}
	else if( !m_SMat.empty() )
	{
		RenderObj::GetInstance()->SetSMat( m_SMat );
	}

	RenderObj::GetInstance()->Paint( m_ObjName );
	RenderObj::GetInstance()->ClearResetMaterials();

 	for( std::vector<RenderNode*>::iterator rnit = m_ChidlRenderNodes.begin(); 
 		rnit != m_ChidlRenderNodes.end(); rnit ++ )
 	{
 		RenderNode* rn = *rnit;
		if( rn == NULL )
		{
			std::cout<< "(RenderNode)::Show() Fatal error\n";
			exit(-1);
		}
 		rn->Paint();
 	}

	glPopMatrix();
}